import json
import re

from django.contrib.auth import login
from django.http import HttpResponse
from django.http import HttpResponseBadRequest
from django.http import HttpResponseForbidden
from django.http import JsonResponse
from django.shortcuts import render, redirect
from QQLoginTool.QQtool import OAuthQQ
from django.conf import settings
from django.views import View
from django_redis import get_redis_connection
from weibo import APIClient

from oauth.models import OAuthQQUser, WeiboUser
from oauth.utils import encode_openid, decode_openid
from users.models import User


class OAuthQQLoginView(View):
    def get(self, request):
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI, state=next)

        login_url = oauth.get_qq_url()
        print(login_url)
        return redirect(login_url)


class OAuthUserView(View):
    def get(self, request):
        code = request.GET.get('code')
        state = request.GET.get('state')

        if not code:
            return HttpResponseForbidden('code is lost')

        oauth_qq = OAuthQQ(client_id=settings.QQ_CLIENT_ID,
                           client_secret=settings.QQ_CLIENT_SECRET,
                           redirect_uri=settings.QQ_REDIRECT_URI,
                           state=state)
        access_token = oauth_qq.get_access_token(code)

        # 3,通过access_token换取openid
        openid = oauth_qq.get_open_id(access_token)

        try:
            # openid存在则直接登录
            user_openid = OAuthQQUser.objects.get(openid=openid)
            user = user_openid.user

            response = redirect('/')
            request.session.set_expiry(None)
            response.set_cookie('username', user.username, expires=3600 * 24 * 14)

            return response

        except Exception as e:

            signed_openid = encode_openid(openid)

            context = {
                'openid': signed_openid
            }

            return render(request, 'oauth_callback.html', context=context)

    def post(self, request):

        phone = request.POST.get('mobile')
        password = request.POST.get('pwd')
        sms_code = request.POST.get('sms_code')
        signed_openid = request.POST.get('openid')

        # print([phone, password, sms_code, openid])
        if not all([phone, password, sms_code, signed_openid]):
            return HttpResponseForbidden('arguments lost')

        # openid解密
        openid = decode_openid(signed_openid)

        if not openid:
            return HttpResponseForbidden('openid错误')

        try:
            # 已注册的账号绑定QQ号
            user = User.objects.get(mobile=phone)

            if user.check_password(raw_password=password):
                OAuthQQUser.objects.create(openid=openid, user=user)

                login(request, user)

                request.session.set_expiry(None)

                response = redirect('/')
                response.set_cookie('username', user.username, expires=3600 * 24 * 14)

                return response

            else:
                return HttpResponseForbidden('密码错误')

        except Exception as e:
            user = User.objects.create_user(username=phone, password=password, mobile=phone)
            OAuthQQUser.objects.create(openid=openid, user=user)

            login(request, user)

            response = redirect('/')
            request.session.set_expiry(None)
            response.set_cookie('username', user.username, expires=3600 * 24 * 7)

            return response


class WeiboLoginView(View):
    def get(self, request):

        next = request.GET.get('next')

        client = APIClient(app_key=settings.APP_KEY,
                           app_secret=settings.APP_SECRET,
                           redirect_uri=settings.REDIRECT_URL)
        login_url = client.get_authorize_url()
        print(login_url, type(login_url), next)

        res = {
            'code': 0,
            'errmsg': 'OK',
            'login_url': login_url + '&state=' + next
        }
        return JsonResponse(res)


class OAuthWeiboUserView(View):

    def get(self, request):

        code = request.GET.get('code')

        if not code:
            return HttpResponseForbidden('missing code')

        client = APIClient(app_key=settings.APP_KEY,
                           app_secret=settings.APP_SECRET,
                           redirect_uri=settings.REDIRECT_URL)

        result = client.request_access_token(code)
        token = result.access_token
        uid = result.uid

        try:
            user_uid = WeiboUser.objects.get(uid=token)

            user = user_uid.user
            login(request, user)

            res = {
                'code': 0,
                'errmsg': 'OK',
                'user_id': user.id,
                'username': user.username,
                'token': token
            }

            response = JsonResponse(res)
            request.session.set_expiry(None)
            response.set_cookie('username', user.username, expires=3600*24*14)
            return response
        except:
            res = {
                'code': 0,
                'errmsg': 'OK',
                'access_token': token
            }
            return JsonResponse(res)


    def post(self, request):

        json_data = request.body

        try:
            json_dict = json.loads(json_data.decode())

        except:
            return HttpResponseForbidden('missing json')

        password = json_dict.get('password')
        mobile = json_dict.get('mobile')
        sms_code = json_dict.get('sms_code')
        access_token = json_dict.get('access_token')

        if not all([password, mobile, sms_code, access_token]):
            return JsonResponse({'code': 9999, 'message': 'missing arguments'}, status=400)

        if not re.match('^[0-9A-Za-z]{8,20}$', password):
            return JsonResponse({'code': 9999, 'message': 'illegal password'}, status=400)

        if not re.match('^1[345789]\d{9}$', mobile):
            return JsonResponse({'code': 9999, 'message': 'illegal mobile'}, status=400)

        redis_client = get_redis_connection('verify_code')
        redis_code = redis_client.get(mobile)

        if redis_code:
            redis_code = redis_code.decode()

        if redis_code != sms_code:
            return JsonResponse({'code': 9999, 'message': '短信验证码错误'}, status=400)

        try:
            user = User.objects.get(mobile=mobile)
            if not user.check_password(raw_password=password):
                return JsonResponse({'code': 9999, 'message': '用户已注册，密码错误'}, status=400)
        except:
            user = User.objects.create_user(username=mobile, mobile=mobile, password=password)

        WeiboUser.objects.create(user=user, uid=access_token)
        login(request, user)

        res = {
            'code': 0,
            'errmsg': 'OK',
            'token': access_token,
            'user_id': user.id,
            'username': user.username,
        }
        response = JsonResponse(res)
        request.session.set_expiry(None)
        response.set_cookie('username', user.username, expires=3600 * 24 * 14)
        return response

#                         // 记录用户登录状态
#                         sessionStorage.clear();
#                         localStorage.clear();
#                         localStorage.token = response.data.token;
#                         localStorage.user_id = response.data.user_id;
#                         localStorage.username = response.data.username;

